package com.codi.api.controller.portfolio;

import com.codi.api.security.UserUtil;
import com.codi.api.validation.AccountValidation;
import com.codi.api.validation.PortfolioValidation;
import com.codi.base.exception.BaseAppException;
import com.codi.base.log.annotation.Loggable;
import com.codi.base.util.StringUtil;
import com.codi.bus.constant.GlobalConstant;
import com.codi.bus.core.domain.FundWarehouseTransfer;
import com.codi.bus.core.fund.FundErrorConst;
import com.codi.bus.core.fund.request.PortfolioTransferRequestDto;
import com.codi.bus.core.resultModel.BaseResult;
import com.codi.bus.core.service.BranchBankService;
import com.codi.bus.core.service.FundWarehouseTransferService;
import com.codi.bus.core.service.PortfolioService;
import com.codi.bus.core.service.PortfolioTransferService;
import com.codi.bus.core.vo.*;
import com.codi.message.constant.ErrorConstant;
import com.codi.message.util.MessageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * 组合投资，交易相关
 *
 * @author spy
 * @version 1.0 2017-11-06 10:51
 * @since 1.0
 */
@Slf4j
@RestController
@RequestMapping("portfolio/trade")
public class PortfolioTradeController {

    @Autowired
    private PortfolioService portfolioService;

    @Autowired
    private PortfolioTransferService portfolioTransferService;

    @Autowired
    private PortfolioValidation portfolioValidation;

    @Autowired
    private AccountValidation accountValidation;

    @Autowired
    private BranchBankService branchBankService;
    @Autowired
    private FundWarehouseTransferService fundWarehouseTransferService;
    /**
     * 交易限制
     *
     * @param portfolioCode
     * @param captialMode
     * @param businCode
     * @return
     */
    @Loggable
    @GetMapping("limits")
    public BaseResult limits(@RequestParam String portfolioCode,
                             @RequestParam String captialMode,
                             @RequestParam String businCode) {

        BaseResult result = portfolioValidation.validateLimits(portfolioCode, captialMode, businCode);
        if (!result.getSuccess()) {
            return result;
        }

        return portfolioService.getLimits(UserUtil.getLoginUserId(), portfolioCode, captialMode, businCode);
    }

    @Loggable
    @PostMapping("limits/sell")
    public BaseResult limits(@Validated @RequestBody PortfolioSellLimitRequestVo vo) {

        BaseResult result = portfolioValidation.validateLimits(vo);
        if (!result.getSuccess()) {
            return result;
        }

        vo.setUserId(UserUtil.getLoginUserId());
        return portfolioService.getSellLimits(vo);
    }

    /**
     * 计算申购费用
     *
     * @param fundCodesStr fundCode|balance
     * @return
     */
    @Loggable
    @GetMapping("/buy_fee")
    public BaseResult calcBuyFee(@RequestParam String fundCodesStr) {
        BaseResult result = new BaseResult();

        return result.setResult(portfolioService.getApplyRate(UserUtil.getLoginUserId(), fundCodesStr));
    }


    /**
     * 计算赎回费用
     *
     * @return
     */
    @Loggable
    @GetMapping("/redeem_fee")
    public BaseResult calcRedeemFee(@RequestParam String fundCodesStr) {
        BaseResult result = new BaseResult();

        return result.setResult(portfolioService.getRedeemRate(UserUtil.getLoginUserId(), fundCodesStr));
    }

    /**
     * 组合的交易详情
     *
     * @param portfolioCode
     * @return
     */
    @Loggable
    @GetMapping("detail")
    public BaseResult detail(@RequestParam String portfolioCode) {

        return portfolioService.getTradeDetail(UserUtil.getLoginUserId(), portfolioCode);
    }

    /**
     * 申购
     *
     * @param buyVo
     * @return
     */
    @Loggable
    @PostMapping("/buy")
    public BaseResult buy(@Validated PortfolioTradeBuyVo buyVo,
                          @RequestHeader(GlobalConstant.HEADER_OS_TYPE) String osType) {
        BaseResult result;

        result = portfolioValidation.validateBuy(buyVo);
        if (!result.getSuccess()) {
            return result;
        }

        SessionVo sessionVo = new SessionVo();
        sessionVo.setUserId(UserUtil.getLoginUserId())
                 .setChannelId(osType);

        result = portfolioService.buy(sessionVo, buyVo);

        return result;
    }

    /**
     * 赎回
     *
     * @param sellVo
     * @return
     */
    @Loggable
    @PostMapping("sell")
    public BaseResult sell(@Validated PortfolioTradeSellVo sellVo,
                           @RequestHeader(GlobalConstant.HEADER_OS_TYPE) String osType) throws BaseAppException {
        BaseResult result;

        result = portfolioValidation.validateSell(sellVo);
        if (!result.getSuccess()) {
            return result;
        }

        SessionVo sessionVo = new SessionVo();
        sessionVo.setUserId(UserUtil.getLoginUserId())
                 .setChannelId(osType);

        result = portfolioService.sell38(sessionVo, sellVo);


        return result;
    }

    /**
     * 赎回v2
     *
     * @param sellVo
     * @return
     */
    @Loggable
    @PostMapping("sell/v2")
    public BaseResult sellv2(@Validated PortfolioTradeSellVo sellVo,@RequestParam String vcBranchbank,
                           @RequestParam String vcBankname,
                           @RequestHeader(GlobalConstant.HEADER_OS_TYPE) String osType) throws BaseAppException {
        BaseResult result;

        result = portfolioValidation.validateSell(sellVo);
        if (!result.getSuccess()) {
            return result;
        }

        //支行修改
        BaseResult resultV = null;
        resultV = accountValidation.setBranchBankValidate(vcBranchbank,sellVo.getTradePassword());
        if (resultV != null){
            return resultV;
        }
        resultV = branchBankService.setBranchBank(UserUtil.getLoginUserId(), vcBranchbank, vcBankname, sellVo.getTradePassword());
        if (!resultV.getSuccess()){
            return resultV;
        }

        SessionVo sessionVo = new SessionVo();
        sessionVo.setUserId(UserUtil.getLoginUserId())
            .setChannelId(osType);

        result = portfolioService.sell38(sessionVo, sellVo);



        return result;
    }

    /**
     * 撤单
     *
     * @return
     */
    @Loggable
    @PostMapping("undo")
    public BaseResult undo(@Validated PortfolioTradeUndoVo undoVo,
                           @RequestHeader(GlobalConstant.HEADER_OS_TYPE) String osType) {
        BaseResult result;

        result = portfolioValidation.validateUndo(undoVo);
        if (!result.getSuccess()) {
            return result;
        }

        SessionVo sessionVo = new SessionVo();
        sessionVo.setUserId(UserUtil.getLoginUserId())
                 .setChannelId(osType);

        result = portfolioService.undo(sessionVo, undoVo);

        return result;
    }

    @Loggable
    @PostMapping("/transfer")
    public BaseResult transfer(@Validated PortfolioTransferRequestDto dto) {
        dto.setUserId(UserUtil.getLoginUserId());
        return portfolioTransferService.transfer(dto);
    }


    @Loggable
    @GetMapping("/goTransfer")
    public BaseResult goTransfer(@RequestParam String transferId){
        BaseResult result = new BaseResult();
        result.setSuccess(false);
        if (StringUtil.isEmpty(transferId)) {
            result.setErrorCode(ErrorConstant.ERROR_FIELD_NO_FIND);
            Map<String, String> map = new HashMap<>();
            map.put(ErrorConstant.PLACEHOLDER_FIELD_NO_FIND_FIELD, "调仓记录主键");
            result.setErrorMessage(MessageUtil.getErrorMessage(ErrorConstant.ERROR_FIELD_NO_FIND, map));
            return result;
        }
        FundWarehouseTransfer fundWarehouseTransfer = fundWarehouseTransferService.selectOne(Long.valueOf(transferId));
        if (fundWarehouseTransfer == null) {
            result.setErrorCode(FundErrorConst.PORTFOLIO_TRANSFER_NOT_EXIST);
            result.setErrorMessage(MessageUtil.getErrorMsg(FundErrorConst.PORTFOLIO_TRANSFER_NOT_EXIST));
            return result;
        }
        result.setSuccess(true);
        result.setResult(fundWarehouseTransfer.getTransferContent());
        return result;
    }
}
